package service

import (
	"errors"

	"wms/internal/model"
	"wms/internal/model/request"
	"wms/internal/model/response"
	"wms/pkg/database"

	"gorm.io/gorm"
)

// MenuService 菜单服务
type MenuService struct {
	db *gorm.DB
}

// NewMenuService 创建菜单服务
func NewMenuService() *MenuService {
	return &MenuService{
		db: database.GetDB(),
	}
}

// List 获取菜单列表
func (s *MenuService) List(req request.MenuListRequest) (*response.MenuListResponse, error) {
	var menus []*model.Menu
	var total int64

	// 构建查询条件
	query := s.db.Model(&model.Menu{})
	if req.Status != 0 {
		query = query.Where("status = ?", req.Status)
	}
	if req.Title != "" {
		query = query.Where("title LIKE ?", "%"+req.Title+"%")
	}
	if req.Path != "" {
		query = query.Where("path LIKE ?", "%"+req.Path+"%")
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, err
	}

	// 分页查询
	if req.Page > 0 && req.Size > 0 {
		offset := (req.Page - 1) * req.Size
		query = query.Offset(offset).Limit(req.Size)
	}

	// 排序
	query = query.Order("sort")

	// 执行查询
	if err := query.Find(&menus).Error; err != nil {
		return nil, err
	}

	// 按照树形结构组织菜单数据
	menuTree := response.BuildMenuTree(menus)

	// 构建响应
	return &response.MenuListResponse{
		Total: total,
		List:  menuTree,
	}, nil
}

// GetUserMenus 获取用户菜单
func (s *MenuService) GetUserMenus(userID uint) ([]*response.MenuResponse, error) {
	// 查询用户信息，获取角色ID
	var user model.User
	if err := s.db.Where("id = ?", userID).First(&user).Error; err != nil {
		return nil, err
	}

	// 查询角色菜单
	var menus []*model.Menu
	if err := s.db.Joins("LEFT JOIN role_menus ON menus.id = role_menus.menu_id").
		Where("role_menus.role_id = ? AND menus.status = 1", user.RoleID).
		Order("menus.sort").
		Find(&menus).Error; err != nil {
		return nil, err
	}

	// 构建菜单树
	return response.BuildMenuTree(menus), nil
}

// GetById 根据ID获取菜单
func (s *MenuService) GetById(id uint) (*model.Menu, error) {
	var menu model.Menu
	if err := s.db.Where("id = ?", id).First(&menu).Error; err != nil {
		return nil, err
	}
	return &menu, nil
}

// Create 创建菜单
func (s *MenuService) Create(req request.MenuCreateRequest) (*model.Menu, error) {
	// 检查父菜单是否存在
	if req.ParentID != 0 {
		var parentMenu model.Menu
		if err := s.db.Where("id = ?", req.ParentID).First(&parentMenu).Error; err != nil {
			return nil, errors.New("父菜单不存在")
		}
	}

	// 创建菜单
	menu := &model.Menu{
		ParentID:  req.ParentID,
		Name:      req.Name,
		Path:      req.Path,
		Component: req.Component,
		Redirect:  req.Redirect,
		Title:     req.Title,
		Icon:      req.Icon,
		Sort:      req.Sort,
		Hidden:    req.Hidden,
		KeepAlive: req.KeepAlive,
		IsFrame:   req.IsFrame,
		Status:    req.Status,
	}

	if err := s.db.Create(menu).Error; err != nil {
		return nil, err
	}

	return menu, nil
}

// Update 更新菜单
func (s *MenuService) Update(req request.MenuUpdateRequest) (*model.Menu, error) {
	// 查询菜单是否存在
	var menu model.Menu
	if err := s.db.Where("id = ?", req.ID).First(&menu).Error; err != nil {
		return nil, errors.New("菜单不存在")
	}

	// 检查父菜单是否存在
	if req.ParentID != 0 && req.ParentID != menu.ParentID {
		var parentMenu model.Menu
		if err := s.db.Where("id = ?", req.ParentID).First(&parentMenu).Error; err != nil {
			return nil, errors.New("父菜单不存在")
		}
	}

	// 更新菜单
	menu.ParentID = req.ParentID
	menu.Name = req.Name
	menu.Path = req.Path
	menu.Component = req.Component
	menu.Redirect = req.Redirect
	menu.Title = req.Title
	menu.Icon = req.Icon
	menu.Sort = req.Sort
	menu.Hidden = req.Hidden
	menu.KeepAlive = req.KeepAlive
	menu.IsFrame = req.IsFrame
	menu.Status = req.Status

	if err := s.db.Save(&menu).Error; err != nil {
		return nil, err
	}

	return &menu, nil
}

// Delete 删除菜单
func (s *MenuService) Delete(id uint) error {
	// 检查是否有子菜单
	var count int64
	if err := s.db.Model(&model.Menu{}).Where("parent_id = ?", id).Count(&count).Error; err != nil {
		return err
	}
	if count > 0 {
		return errors.New("存在子菜单，不能删除")
	}

	// 删除菜单
	if err := s.db.Delete(&model.Menu{}, id).Error; err != nil {
		return err
	}

	// 删除角色菜单关联
	if err := s.db.Where("menu_id = ?", id).Delete(&model.RoleMenu{}).Error; err != nil {
		return err
	}

	return nil
}
